#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include <QDir>

#include "../model/LocalUserModel.h"
#include "../global/QmlNames.h"
#include "../util/Singleton.h"
#include "Config.h"

X_BEGIN_NAMESPACE

const char Config::VCards[] = "vcards";
const char Config::Images[] = "images";

// 应用程序配置JSON文件路径，相对于RESOURCES目录
const QString Config::JSON_FILE = "config/app.config.json";

Config::Config()
    : QObject(NULL){
    this->init();
}

Config& Config::instance(){
    return *Singleton<Config>::instance(Config::createInstance);
}

const char *Config::qmlName()
{
    return QmlNames::TopLevelModelSingleton::ConfigSingleton;
}

QObject *Config::qmlInstance(QQmlEngine* engine, QJSEngine* jsEngine)
{
    Q_UNUSED(engine);
    Q_UNUSED(jsEngine);

    return &instance();
}

void Config::init() {
    QFile file(resourcesPath()  + JSON_FILE);
    file.open(QIODevice::ReadOnly | QIODevice::Text);

    m_json = QJsonDocument::fromJson(file.readAll()).object();

    file.close();
}

Config *Config::createInstance()
{
    return new Config();
}

QString Config::domain(bool appendPrefix) const{
    QJsonValue server = m_json["server"];
    QString domain = server.toObject()["domain"].toString();

    return appendPrefix ? "@" + domain : domain;
}

int Config::port() const{
    QJsonValue server = m_json["server"];
    int port = server.toObject()["port"].toInt();

    return port;
}

int Config::sslPort() const{
    QJsonValue server = m_json["server"];
    int sslPort = server.toObject()["ssl_port"].toInt();

    return sslPort;
}

bool Config::ignoreSslError() const
{
    QJsonValue server = m_json["server"];
    QJsonValue value = server.toObject()["ignore_ssl_error"];

    return value.toBool();
}

QString Config::defaultAvatar() const
{
    return "qrc:/images/avatar_default.png";
}

QString Config::cloudDesktopHome() const
{
    QJsonValue cloudDesktop = m_json["cloud_desktop"];
    QJsonValue value = cloudDesktop.toObject()["home"];

    return value.toString();
}

bool Config::rememberPassword() const
{
    QJsonValue value = m_json["remember_password"];

    return value.toBool();
}

bool Config::autoLogin() const
{
    QJsonValue value = m_json["auto_login"];

    return value.toBool();
}

/**
 * @brief 本地数据存储路径。在data目录下，以bareJid分类。
 * @return
 */
QString Config::storagePath(const QString& bareJid, const QString& subPath) const
{
    QString basePath = QCoreApplication::applicationDirPath() + QDir::separator() + "data" + QDir::separator();
    QString path = basePath + bareJid + QDir::separator();
    if(!subPath.isEmpty()) path += subPath + QDir::separator();

    QDir dir(path);
    if(!dir.exists())
    {
        dir.mkpath(path);
    }

    return path;
}

/**
 * @brief 本地资源路径。在resources目录下。
 * @return
 */
QString Config::resourcesPath() const
{
    QString basePath = QCoreApplication::applicationDirPath() + QDir::separator() + "resources" + QDir::separator();
    return basePath;
}

Config &Config::setDomain(QString domain)
{
    QJsonValue server = m_json["server"];
    if (server.toObject()["domain"].toString() == domain)
        return *this;

    server.toObject()["domain"] = domain;
    emit domainChanged(domain);

    return *this;
}

Config &Config::setPort(int port)
{
    QJsonValue server = m_json["server"];
    if (server.toObject()["port"].toInt() == port)
        return *this;

    server.toObject()["port"] = port;
    emit portChanged(port);

    return *this;
}

Config &Config::setSslPort(int sslPort)
{
    QJsonValue server = m_json["server"];
    if (server.toObject()["ssl_port"].toInt() == sslPort)
        return *this;

    server.toObject()["ssl_port"] = sslPort;
    emit sslPortChanged(sslPort);

    return *this;
}

Config &Config::setIgnoreSslError(bool ignoreSelfSignedCert)
{
    QJsonValue server = m_json["server"];
    QJsonValue value = server.toObject()["ignore_ssl_error"];
    if (value.toBool() == ignoreSelfSignedCert)
        return *this;

    value = ignoreSelfSignedCert;

    return *this;
}

Config &Config::setCloudDesktopHome(QString cloudDekstopHome)
{
    QJsonValue cloudDesktop = m_json["cloud_desktop"];
    QJsonValue value = cloudDesktop.toObject()["home"];

    if (value.toString() == cloudDekstopHome)
        return *this;

    value = cloudDekstopHome;
    emit cloudDesktopHomeChanged(cloudDekstopHome);

    return *this;
}

Config &Config::setRememberPassword(bool rememberPassword)
{
    QJsonValue value = m_json["remember_password"];
    if (value.toBool() == rememberPassword)
        return *this;

    value = rememberPassword;
    emit rememberPasswordChanged(rememberPassword);

    return *this;
}

Config &Config::setAutoLogin(bool autoLogin)
{
    QJsonValue value = m_json["auto_login"];
    if (value.toBool() == autoLogin)
        return *this;

    value = autoLogin;
    emit autoLoginChanged(autoLogin);

    return *this;
}

X_END_NAMESPACE
